const { prisma } = require('../config/prisma');

class UserPrisma {
  constructor(data) {
    this.id = data.id;
    this.openid = data.openid;
    this.nickname = data.nickname;
    this.avatar_url = data.avatar_url;
    this.phone_number = data.phone_number;
    this.wechat_id = data.wechat_id;
    this.union_id = data.union_id;
    this.status = data.status;
    this.chat_banned = data.chat_banned;
    this.publishing_credits = Number(data.publishing_credits ?? 0);
    this.chat_credits = Number(data.chat_credits ?? 0);
    this.contact_view_credits = Number(data.contact_view_credits ?? 0);
    this.last_known_ip = data.last_known_ip;
    this.last_known_province = data.last_known_province;
    this.last_known_city = data.last_known_city;
    this.location_updated_at = data.location_updated_at;
    this.local_service_credits = Number(data.local_service_credits ?? 0);
    this.inviter_id = data.inviter_id;
    this.created_at = data.created_at;
    this.updated_at = data.updated_at;
  }

  /**
   * 根据openid查找用户
   * @param {string} openid 微信openid
   * @returns {Promise<UserPrisma|null>}
   */
  static async findByOpenid(openid) {
    const user = await prisma.users.findUnique({
      where: { openid }
    });
    return user ? new UserPrisma(user) : null;
  }

  /**
   * 根据 UnionID 查找用户
   * @param {string} unionId 微信开放平台 unionId
   * @returns {Promise<UserPrisma|null>}
   */
  static async findByUnionId(unionId) {
    if (!unionId) {
      return null;
    }

    const user = await prisma.users.findUnique({
      where: { union_id: unionId }
    });
    return user ? new UserPrisma(user) : null;
  }

  /**
   * 根据ID查找用户
   * @param {number} id 用户ID
   * @returns {Promise<UserPrisma|null>}
   */
  static async findById(id) {
    // 检查 id 是否为有效值
    if (id === null || id === undefined) {
      return null;
    }

    const user = await prisma.users.findUnique({
      where: { id: BigInt(id) }
    });
    return user ? new UserPrisma(user) : null;
  }

  /**
   * 创建新用户
   * @param {Object} userData 用户数据
   * @returns {Promise<UserPrisma>}
   */
  static async create(userData) {
    const user = await prisma.users.create({
      data: {
        openid: userData.openid,
        union_id: userData.union_id || null,
        nickname: userData.nickname || null,
        avatar_url: userData.avatar_url || null,
        phone_number: userData.phone_number || null,
        status: userData.status || 'inactive',
        publishing_credits: userData.publishing_credits || 0,
        inviter_id: userData.inviter_id ? BigInt(userData.inviter_id) : null,
        last_known_ip: userData.last_known_ip || null,
        last_known_province: userData.last_known_province || null,
        last_known_city: userData.last_known_city || null,
        location_updated_at: userData.location_updated_at || null
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 更新用户信息
   * @param {number} id 用户ID
   * @param {Object} updateData 更新数据
   * @returns {Promise<UserPrisma>}
   */
  static async update(id, updateData) {
    // 处理BigInt字段
    const data = { ...updateData };
    if (data.inviter_id !== undefined && data.inviter_id !== null) {
      data.inviter_id = BigInt(data.inviter_id);
    }

    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data
    });
    return new UserPrisma(user);
  }

  /**
   * 更新最后登录时间
   * @param {number} id 用户ID
   * @returns {Promise<void>}
   */
  static async updateLastLogin(id) {
    await prisma.users.update({
      where: { id: BigInt(id) },
      data: { updated_at: new Date() }
    });
  }

  /**
   * 统一更新 openid / unionId 绑定关系
   * @param {number|bigint} id 用户ID
   * @param {{openid?: string, union_id?: string}} payload
   * @returns {Promise<UserPrisma>}
   */
  static async updateOpenPlatformBindings(id, payload) {
    const data = {};
    if (payload.openid) {
      data.openid = payload.openid;
    }
    if (payload.union_id) {
      data.union_id = payload.union_id;
    }

    if (Object.keys(data).length === 0) {
      const user = await prisma.users.findUnique({ where: { id: BigInt(id) } });
      return user ? new UserPrisma(user) : null;
    }

    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data
    });
    return new UserPrisma(user);
  }

  /**
   * 增加发布额度
   * @param {number} id 用户ID
   * @param {number} credits 增加的额度
   * @returns {Promise<UserPrisma>}
   */
  static async addCredits(id, credits) {
    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        publishing_credits: {
          increment: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 减少发布额度
   * @param {number} id 用户ID
   * @param {number} credits 减少的额度
   * @returns {Promise<UserPrisma>}
   */
  static async reduceCredits(id, credits = 1) {
    // 先检查用户当前额度
    const currentUser = await prisma.users.findUnique({
      where: { id: BigInt(id) },
      select: { publishing_credits: true }
    });

    if (!currentUser || currentUser.publishing_credits < credits) {
      throw new Error('发布额度不足');
    }

    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        publishing_credits: {
          decrement: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 更新发布额度
   * @param {number} id 用户ID
   * @param {number} credits 新的额度值
   * @returns {Promise<UserPrisma>}
   */
  static async updateCredits(id, credits) {
    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        publishing_credits: credits
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 增加聊天消息额度
   * @param {number} id 用户ID
   * @param {number} credits 增加的额度
   * @returns {Promise<UserPrisma>}
   */
  static async addChatCredits(id, credits) {
    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        chat_credits: {
          increment: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 增加查看手机号额度
   * @param {number} id 用户ID
   * @param {number} credits 增加的额度
   * @returns {Promise<UserPrisma>}
   */
  static async addContactViewCredits(id, credits) {
    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        contact_view_credits: {
          increment: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 减少查看手机号额度
   * @param {number} id 用户ID
   * @param {number} credits 减少的额度
   * @returns {Promise<UserPrisma>}
   */
  static async reduceContactViewCredits(id, credits = 1) {
    // 先检查用户当前额度
    const currentUser = await prisma.users.findUnique({
      where: { id: BigInt(id) },
      select: { contact_view_credits: true }
    });

    if (!currentUser) {
      throw new Error('用户不存在');
    }

    if (currentUser.contact_view_credits < credits) {
      throw new Error('查看次数不足');
    }

    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        contact_view_credits: {
          decrement: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 增加本地服务信用
   * @param {number} id 用户ID
   * @param {number} credits 增加的信用
   * @returns {Promise<UserPrisma>}
   */
  static async addLocalServiceCredits(id, credits) {
    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        local_service_credits: {
          increment: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 减少本地服务信用
   * @param {number} id 用户ID
   * @param {number} credits 减少的信用
   * @returns {Promise<UserPrisma>}
   */
  static async reduceLocalServiceCredits(id, credits = 1) {
    // 先检查用户当前信用
    const currentUser = await prisma.users.findUnique({
      where: { id: BigInt(id) },
      select: { local_service_credits: true }
    });

    if (!currentUser) {
      throw new Error('用户不存在');
    }

    if (currentUser.local_service_credits < credits) {
      throw new Error('本地服务发布信用不足');
    }

    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        local_service_credits: {
          decrement: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 减少聊天消息额度
   * @param {number} id 用户ID
   * @param {number} credits 减少的额度
   * @returns {Promise<UserPrisma>}
   */
  static async reduceChatCredits(id, credits = 1) {
    // 先检查用户当前额度
    const currentUser = await prisma.users.findUnique({
      where: { id: BigInt(id) },
      select: { chat_credits: true }
    });

    if (!currentUser || currentUser.chat_credits < credits) {
      throw new Error('聊天消息额度不足');
    }

    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        chat_credits: {
          decrement: credits
        }
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 更新聊天消息额度
   * @param {number} id 用户ID
   * @param {number} credits 新的额度值
   * @returns {Promise<UserPrisma>}
   */
  static async updateChatCredits(id, credits) {
    const user = await prisma.users.update({
      where: { id: BigInt(id) },
      data: {
        chat_credits: credits
      }
    });
    return new UserPrisma(user);
  }

  /**
   * 激活用户
   * @param {number} id 用户ID
   * @returns {Promise<UserPrisma>}
   */
  static async activate(id) {
    return await UserPrisma.update(id, { status: 'active' });
  }

  /**
   * 禁言用户
   * @param {number} id 用户ID
   * @returns {Promise<UserPrisma>}
   */
  static async banChat(id) {
    return await UserPrisma.update(id, { chat_banned: true });
  }

  /**
   * 解除禁言
   * @param {number} id 用户ID
   * @returns {Promise<UserPrisma>}
   */
  static async unbanChat(id) {
    return await UserPrisma.update(id, { chat_banned: false });
  }

  /**
   * 检查用户是否被禁言
   * @param {number} id 用户ID
   * @returns {Promise<boolean>}
   */
  static async isChatBanned(id) {
    const user = await prisma.users.findUnique({
      where: { id: BigInt(id) },
      select: { chat_banned: true }
    });
    return user ? user.chat_banned : false;
  }

  /**
   * 获取用户统计信息
   * @returns {Promise<Object>}
   */
  static async getStats() {
    const [total, active, today] = await Promise.all([
      prisma.users.count(),
      prisma.users.count({
        where: { status: 'active' }
      }),
      prisma.users.count({
        where: {
          created_at: {
            gte: new Date(new Date().setHours(0, 0, 0, 0))
          }
        }
      })
    ]);

    return { total, active, today };
  }

  /**
   * 获取用户列表（分页）
   * @param {Object} options 查询选项
   * @returns {Promise<Object>}
   */
  static async getList(options = {}) {
    const {
      page = 1,
      pageSize = 10,
      status,
      search
    } = options;

    const pageNum = parseInt(page);
    const pageSizeNum = parseInt(pageSize);
    const skip = (pageNum - 1) * pageSizeNum;

    // 构建where条件
    const where = {};
    
    if (status) {
      where.status = status;
    }

    if (search) {
      where.OR = [
        { nickname: { contains: search } },
        { phone_number: { contains: search } }
      ];
    }

    // 并行查询总数和列表数据
    const [total, users] = await Promise.all([
      prisma.users.count({ where }),
      prisma.users.findMany({
        where,
        orderBy: { created_at: 'desc' },
        skip,
        take: pageSizeNum
      })
    ]);

    return {
      data: users.map(user => new UserPrisma(user)),
      pagination: {
        page: pageNum,
        pageSize: pageSizeNum,
        total,
        totalPages: Math.ceil(total / pageSizeNum)
      }
    };
  }

  /**
   * 转换为JSON对象（隐藏敏感信息）
   * @returns {Object}
   */
  toJSON() {
    return {
      id: this.id.toString(), // BigInt转字符串
      nickname: this.nickname,
      avatar_url: this.avatar_url,
      phone_number: this.phone_number,
      wechat_id: this.wechat_id,
      status: this.status,
      chat_banned: this.chat_banned,
      publishing_credits: this.publishing_credits,
      chat_credits: this.chat_credits,
      contact_view_credits: this.contact_view_credits,
      last_known_ip: this.last_known_ip,
      last_known_province: this.last_known_province,
      last_known_city: this.last_known_city,
      location_updated_at: this.location_updated_at,
      local_service_credits: this.local_service_credits,
      created_at: this.created_at,
      updated_at: this.updated_at
    };
  }
}

module.exports = UserPrisma;
